package admin

import (
	"baokaobang/conf"
	"baokaobang/datasourse"
	"baokaobang/logic"
	"baokaobang/models"
	"baokaobang/utils"
	"encoding/json"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/mvc"
	"github.com/kataras/iris/v12/sessions"
	"strings"
)

type StudentScore struct {
	Ctx iris.Context
}

type StudentScoreExcelCreate struct {
	Name     string `json:"name"`
	ExcelUrl string `json:"excelUrl"`
}

type StudentScoreListParam struct {
	TestName      string `json:"testName"`
	StudentName   string `json:"studentName"`
	StudentIdcard string `json:"studentIdcard"`
	PerPage       int    `json:"perPage"`
	CurPage       int    `json:"curPage"`
}

func (c *StudentScore) OptionsExcel() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c *StudentScore) PostExcel() interface{} {
	studentScoreExcelCreate := StudentScoreExcelCreate{}
	content, err := c.Ctx.GetBody()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("接受请求参数出错:%s", err.Error()), "")
	}
	err = json.Unmarshal(content, &studentScoreExcelCreate)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("参数解析出错:%s", err.Error()), "")
	}

	if len(studentScoreExcelCreate.Name) <= 0 {
		return utils.CommonRes(1000, "请输入考试名称", "")
	}
	if len(studentScoreExcelCreate.ExcelUrl) <= 0 {
		return utils.CommonRes(1000, "请上传excel文件", "")
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	session := sessions.Get(c.Ctx)
	adminUserId, _ := session.GetInt64("adminUserId")

	sess := db.NewSession()
	defer sess.Close()
	err = sess.Begin()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("数据库事务开启失败：%s", err.Error()), "")
	}

	filePath := fmt.Sprintf("%s%s", conf.UploadPrefix.Backend, studentScoreExcelCreate.ExcelUrl)
	f, err := excelize.OpenFile(filePath)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("上传的文件无法打开:%s", err.Error()), "")
	}

	siteConfig := new(models.SiteConfig)
	_, err = sess.ID(1).Get(siteConfig)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("网站配置信息查询出错：%s", err.Error()), "")
	}

	sheetList := f.GetSheetMap()
	for _, sheet := range sheetList {
		rows := f.GetRows(sheet)
		for i, row := range rows {
			if i == 0 {
				continue
			}

			score := utils.Atoi(row[2])

			student := new(models.User)
			ok, _ := db.Where("name = ? and idcard = ?", row[0], row[1]).Get(student)
			if !ok {
				return utils.CommonRes(1000, fmt.Sprintf("姓名：%s 身份证：%s 不存在，请仔细检查", row[0], row[1]), "")
			}

			studentScore := new(models.StudentScore)
			studentScore.UserId = student.Id
			studentScore.AdminId = adminUserId
			studentScore.TestName = studentScoreExcelCreate.Name
			studentScore.StudentScore = score
			_, err = sess.InsertOne(studentScore)
			if err != nil {
				return utils.CommonRes(1000, fmt.Sprintf("数据导入失败：%s", err.Error()), "")
			}

			// 根据学生成绩更新学生信息，并为学生匹配院校
			res := logic.MatchCollege(sess, student.Id, score)
			if res["code"] != 20000 {
				return res
			}
		}
	}

	sess.Commit()

	return utils.CommonRes(20000, "数据导入成功", "")
}

func (c *StudentScore) OptionsList() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c *StudentScore) PostList() interface{} {
	studentScoreListParam := StudentScoreListParam{}
	content, err := c.Ctx.GetBody()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("接收请求参数出错:%s", err.Error()), "")
	}
	err = json.Unmarshal(content, &studentScoreListParam)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("解析请求参数出错:%s", err.Error()), "")
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库:%s", err.Error()), "")
	}

	session := sessions.Get(c.Ctx)
	adminUserId, _ := session.GetInt64("adminUserId")

	adminUser := new(models.Admin)
	ok, _ := db.ID(adminUserId).Get(adminUser)
	if !ok {
		return utils.CommonRes(1000, "无法获取当前管理员信息", "")
	}

	role := new(models.Role)
	ok, _ = db.ID(adminUser.RoleId).Get(role)
	if !ok {
		return utils.CommonRes(1000, "无法获取当前管理员角色信息", "")
	}

	start := (studentScoreListParam.CurPage - 1) * studentScoreListParam.PerPage
	studentScoreList := make([]models.StudentScoreObj, 0)
	sess := db.Table("student_score").Alias("ss").
		Join("INNER", []string{"user", "u"}, "ss.user_id = u.id").
		Limit(studentScoreListParam.PerPage, start)
	if !strings.EqualFold(role.Authorities, "admin") {
		sess = sess.Where("ss.admin_id = ?", adminUser.Id)
	}
	if len(studentScoreListParam.TestName) > 0 {
		sess = sess.Where("ss.test_name like ?", fmt.Sprintf("%%%s%%", studentScoreListParam.TestName))
	}
	if len(studentScoreListParam.StudentName) > 0 {
		sess = sess.Where("u.name like ?", fmt.Sprintf("%%%s%%", studentScoreListParam.StudentName))
	}
	if len(studentScoreListParam.StudentIdcard) > 0 {
		sess = sess.Where("u.idcard like ?", fmt.Sprintf("%%%s%%", studentScoreListParam.StudentIdcard))
	}
	err = sess.Find(&studentScoreList)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法获取学生成绩列表:%s", err.Error()), "")
	}

	countSess := db.Table("student_score").Alias("ss").
		Join("INNER", []string{"user", "u"}, "ss.user_id = u.id")
	if !strings.EqualFold(role.Authorities, "admin") {
		sess = sess.Where("ss.admin_id = ?", adminUser.Id)
	}
	if len(studentScoreListParam.TestName) > 0 {
		countSess = countSess.Where("ss.test_name like ?", fmt.Sprintf("%%%s%%", studentScoreListParam.TestName))
	}
	if len(studentScoreListParam.StudentName) > 0 {
		countSess = countSess.Where("u.name like ?", fmt.Sprintf("%%%s%%", studentScoreListParam.StudentName))
	}
	if len(studentScoreListParam.StudentIdcard) > 0 {
		sess = sess.Where("u.idcard like ?", fmt.Sprintf("%%%s%%", studentScoreListParam.StudentIdcard))
	}
	total, err := countSess.Count()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法获取学生成绩列表:%s", err.Error()), "")
	}

	for i, item := range studentScoreList {
		studentScoreList[i].StudentScore.StudentScoreCreated = item.StudentScore.Created.Format("2006-01-02 15:04")
	}

	data := map[string]interface{}{
		"total": total,
		"list":  studentScoreList,
	}

	return utils.CommonRes(20000, "成功获取学生成绩列表", data)
}
